package org.mspring.mlog.web.admin;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.mspring.mlog.MarkdownUtils;
import org.mspring.mlog.cache.ArticleCacheService;
import org.mspring.mlog.cache.TagCacheService;
import org.mspring.mlog.common.ContentImage;
import org.mspring.mlog.common.exception.OperateException;
import org.mspring.mlog.entity.ArticleEntity;
import org.mspring.mlog.entity.CategoryEntity;
import org.mspring.mlog.entity.TagEntity;
import org.mspring.mlog.entity.UserEntity;
import org.mspring.mlog.common.constants.ContentFormat;
import org.mspring.mlog.common.constants.ArticleStatus;
import org.mspring.mlog.search.ArticleSearchService;
import org.mspring.mlog.service.ArticleEntityService;
import org.mspring.mlog.service.CategoryEntityService;
import org.mspring.mlog.support.ServiceContext;
import org.mspring.mlog.support.TabItem;
import org.mspring.mlog.web.BaseAdminController;
import org.mspring.nbee.common.PageResult;
import org.mspring.nbee.db.dao.sql.builder.part.condition.Operator;
import org.mspring.nbee.db.dao.sql.builder.part.condition.SqlCondition;
import org.mspring.nbee.db.dao.sql.builder.part.condition.impl.SimpleCondition;
import org.mspring.nbee.db.dao.sql.pager.OrderType;
import org.mspring.nbee.db.dao.sql.pager.SqlPager;
import org.mspring.nbee.web.support.QueryParam;
import org.mspring.nbee.web.support.WebContext;
import org.mspring.nbee.web.view.json.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * @author Gao Youbo
 * @since 2014-12-04 17:59
 */
@Controller
@RequestMapping("/admin/article")
@TabItem(item = "100105")
public class ArticleController extends BaseAdminController {

    private ArticleEntityService articleEntityService;
    private CategoryEntityService categoryEntityService;
    private ArticleSearchService articleSearchService;
    private ArticleCacheService articleCacheService;
    private TagCacheService tagCacheService;
    private ServiceContext serviceContext;

    @RequestMapping("/list")
    @TabItem(item = "100105005")
    public String list(WebContext context, Model model) {
        SqlPager pager = context.getPager();
        pager.addOrder("id", OrderType.DESC);
        List<SqlCondition> conditions = context.buildSqlConditions(model,
                new QueryParam(ArticleEntity.Fields.title, Operator.LIKE),
                new QueryParam(ArticleEntity.Fields.category, Operator.EQ)
        );
        conditions.add(new SimpleCondition("status", Operator.EQ, ArticleStatus.NORMAL));
        PageResult<ArticleEntity> result = articleEntityService.list(conditions, pager);
        List<CategoryEntity> categoryList = categoryEntityService.listAll();
        model.addAttribute("result", result);
        model.addAttribute("categoryList", categoryList);
        return "/admin/article/list";
    }

    @RequestMapping("/create/markdown")
    @TabItem(item = "100105010")
    public String createMarkdown(WebContext context, Model model) {
        List<CategoryEntity> categoryList = categoryEntityService.listAll();
        model.addAttribute("format", ContentFormat.MARKDOWN);
        model.addAttribute("categoryList", categoryList);
        model.addAttribute("sessionId", context.getRequest().getSession().getId());
        return "/admin/article/create";
    }

    @RequestMapping("/create/html")
    @TabItem(item = "100105015")
    public String createHtml(WebContext context, Model model) {
        List<CategoryEntity> categoryList = categoryEntityService.listAll();
        model.addAttribute("format", ContentFormat.HTML);
        model.addAttribute("categoryList", categoryList);
        model.addAttribute("sessionId", context.getRequest().getSession().getId());
        return "/admin/article/create";
    }

    @RequestMapping("/create/do")
    public String doCreate(WebContext context, Model model) {
        UserEntity currentUser = getCurrentUser();
        List<String> tags = context.getParamAsStringList("tags");
        ArticleEntity article = context.fromRequest(ArticleEntity.class);

        if (StringUtils.isNotBlank(article.getImageList())) {
            List<ContentImage> images = ContentImage.fromJson(article.getImageList());
            article.setImageList(JSON.toJSONString(images));
        }

        article.setCreateTime(new Date());
        article.setCreateUser(currentUser.getId());
        article.setCreateUserName(currentUser.getNickname());
        article.setUpdateTime(new Date());
        article.setUpdateUser(currentUser.getId());
        article.setUpdateUserName(currentUser.getNickname());
        articleEntityService.createArticle(article, tags, currentUser);
        return "redirect:/admin/article/list";
    }


    @RequestMapping("/edit")
    @TabItem(item = "100105020")
    public String edit(WebContext context, Model model) {
        Long id = context.getParamAsLong("id");
        if (id == null) {
            throw new OperateException("操作异常：请选择要编辑的文章");
        }
        ArticleEntity article = articleEntityService.findById(id);
        List<CategoryEntity> categoryList = categoryEntityService.listAll();
        List<TagEntity> tagList = tagCacheService.getArticleTagList(id);
        model.addAttribute("article", article);
        model.addAttribute("categoryList", categoryList);
        model.addAttribute("tagList", tagList);
        return "/admin/article/edit";
    }


    @RequestMapping("/edit/do")
    public String doEdit(WebContext context, Model model) {
        UserEntity currentUser = getCurrentUser();
        long id = context.getRequiredLong("id");
        List<String> tags = context.getParamAsStringList("tags");
        ArticleEntity article = articleEntityService.findById(id);
        article = context.fromRequest(article);
        article.setUpdateTime(new Date());
        article.setUpdateUser(currentUser.getId());
        article.setUpdateUserName(currentUser.getNickname());
        articleEntityService.updateArticle(article, tags, currentUser);
        return "redirect:/admin/article/list";
    }

    /**
     * markdown内容预览
     *
     * @return
     */
    @RequestMapping("/markdown/preview")
    @ResponseBody
    public JsonResult markdownPreview(WebContext context, Model model) throws IOException {
        String content = context.getParam("content");
        String html = MarkdownUtils.format(content);
        return JsonResult.getJsonResult(html);
    }

    @RequestMapping("/delete/do")
    @ResponseBody
    public JsonResult delete(WebContext context, Model model) {
        long id = context.getRequiredLong("id");
        boolean flag = articleEntityService.deleteById(id);
        return JsonResult.getJsonResult(flag);
    }

    @Autowired
    public void setArticleEntityService(ArticleEntityService articleEntityService) {
        this.articleEntityService = articleEntityService;
    }

    @Autowired
    public void setCategoryEntityService(CategoryEntityService categoryEntityService) {
        this.categoryEntityService = categoryEntityService;
    }

    @Autowired
    public void setArticleSearchService(ArticleSearchService articleSearchService) {
        this.articleSearchService = articleSearchService;
    }

    @Autowired
    public void setArticleCacheService(ArticleCacheService articleCacheService) {
        this.articleCacheService = articleCacheService;
    }

    @Autowired
    public void setTagCacheService(TagCacheService tagCacheService) {
        this.tagCacheService = tagCacheService;
    }

    @Autowired
    public void setServiceContext(ServiceContext serviceContext) {
        this.serviceContext = serviceContext;
    }
}
